package com.mobile.tools;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.math.BigDecimal;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.json.JSONException;
import org.json.JSONObject;

import com.mobile.struts.action.tools.AssociateTableInfo;
/**
 * JavaBean的工具类
 * @author Administrator
 *
 */
public class BeanUtil{
	
	private static final Logger LOGGER = LogManager.getLogger(BeanUtil.class);
	
	public static <T> T copyProperties( T t, Object o )
	{
		try {
			BeanUtils.copyProperties( t, o );
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			LOGGER.error(e);
		} catch (InvocationTargetException e) {
			// TODO Auto-generated catch block
			LOGGER.error(e);
		}
		return t;
	}
	/**
	 * 复制属性，但不包含null
	 * @param <T>
	 * @param t
	 * @param o
	 * @return
	 */
	public static <T> T copyPropertiesWithoutNull(T t,Object o){
		BeanInfo bi;
		try {
			bi = Introspector.getBeanInfo(o.getClass(),Object.class);
			PropertyDescriptor[] pds=bi.getPropertyDescriptors();
			for(PropertyDescriptor pd:pds){	
				if(pd.getReadMethod()!=null&&pd.getReadMethod().invoke(o)!=null){
					pd.getWriteMethod().invoke(t, pd.getReadMethod().invoke(o));
				}				
			}
		} catch (IntrospectionException e) {
			// TODO Auto-generated catch block
			LOGGER.error(e);
		} catch(IllegalAccessException e){
			LOGGER.error(e);
		} catch(InvocationTargetException e){
			LOGGER.error(e);
		} 
		return t;
	}
	
	public static <T> T copyPropertiesClearWhite(T t,Object o){
		BeanInfo bi;
		try {
			bi = Introspector.getBeanInfo(o.getClass(),Object.class);
			PropertyDescriptor[] pds=bi.getPropertyDescriptors();
			for(PropertyDescriptor pd:pds){	
				if(pd.getReadMethod()!=null&&pd.getReadMethod().invoke(o)!=null){
					String value=pd.getReadMethod().invoke(o).toString();
					if("".equals(value)&&"java.lang.String".equals(pd.getPropertyType().getName())&&pd.getWriteMethod()!=null){
						pd.getWriteMethod().invoke(o, null);
					}
				}				
			}
		} catch (IntrospectionException e) {
			// TODO Auto-generated catch block
			LOGGER.error(e);
		} catch(IllegalAccessException e){
			LOGGER.error(e);
		} catch(InvocationTargetException e){
			LOGGER.error(e);
		} 
		return copyProperties(t,o );
	}
	public static <T> T copyPropertiesClearWhite(T t,Map<String,String[]> map){
		Map<String,String> mapTemp=new HashMap<String,String>();
		for(Map.Entry<String, String[]> entry:map.entrySet()){
			String[] value=entry.getValue();
			
			if(value!=null&&!"".equals(ArraysUtil.join(value,","))){
				mapTemp.put(entry.getKey(), ArraysUtil.join(value, ","));
			}
		}
		return copyProperties(t,mapTemp);
	}
	/**
	 * 添加新的属性
	 * @param <T>
	 * @param t
	 * @param o
	 * @return
	 */
	public static <T> T addNewProperties(T t,Object o){
		BeanInfo bi;
		try {
			bi = Introspector.getBeanInfo(o.getClass(),Object.class);
			PropertyDescriptor[] pds=bi.getPropertyDescriptors();
			for(PropertyDescriptor pd:pds){	
				if(pd.getReadMethod()!=null&&pd.getReadMethod().invoke(o)!=null){
					Object newP=pd.getReadMethod().invoke(o);
					pd.getWriteMethod().invoke(t, newP);
				}				
			}
		} catch (IntrospectionException e) {
			// TODO Auto-generated catch block
			LOGGER.error(e);
		} catch(IllegalAccessException e){
			LOGGER.error(e);
		} catch(InvocationTargetException e){
			LOGGER.error(e);
		}
		return t;
	}
	/**
	 * JavaBean装换成map不包含集合属性
	 * @param obj
	 * @return
	 */
	public static Map<String,Object> javaBeanToMap(Object obj){
		Map<String,Object> map=new HashMap<String,Object>();
		try {
			BeanInfo bi=Introspector.getBeanInfo(obj.getClass(), Object.class);
			PropertyDescriptor[] pds=bi.getPropertyDescriptors();
			for(PropertyDescriptor pd:pds){
				String key=pd.getName();
				Object value=pd.getReadMethod().invoke(obj);
				if(value!=null&&!(value instanceof Collection)){
					map.put(key, value);
				}				
			}
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			LOGGER.error(e);
		} catch (IntrospectionException e) {
			// TODO Auto-generated catch block
			LOGGER.error(e);
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			LOGGER.error(e);
		} catch (InvocationTargetException e) {
			// TODO Auto-generated catch block
			LOGGER.error(e);
		}
		return map;
	}
	
	public static Object copyProperties(Object bean , JSONObject jObj){
		try {
			
			for(Iterator it = jObj.sortedKeys();it.hasNext();){
				String key = (String)it.next();
				
				PropertyDescriptor pd = new PropertyDescriptor(key,bean.getClass());
				
				if(pd!=null){
					Object value = jObj.get(key);
					if(value instanceof JSONObject){
						
						Class clazz=pd.getPropertyType();
						Object obj=clazz.newInstance();
						
						obj=copyProperties(obj, (JSONObject)value);
						pd.getWriteMethod().invoke(bean, obj);
					}else{
						//PropertyUtils.copyProperties(bean, map);
						BeanUtils.copyProperty(bean, key, value);
						//pd.getWriteMethod().invoke(bean, value);
					}
				}
			}
			
		} catch (IntrospectionException e) {
			// TODO Auto-generated catch block
			LOGGER.error(e);
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			LOGGER.error(e);
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			LOGGER.error(e);
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			LOGGER.error(e);
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			LOGGER.error(e);
		} catch (InvocationTargetException e) {
			// TODO Auto-generated catch block
			LOGGER.error(e);
		}
		
		return bean;
	}
	public static Object copyProperties(Object bean , List<AssociateTableInfo> list){
		try {			
			for(AssociateTableInfo ati:list){
				String propertyName = ati.getAssociatedName();
				
				PropertyDescriptor pd = new PropertyDescriptor(propertyName,bean.getClass());
				
				if(pd!=null){
					Object value = ati.getBean();
					pd.getWriteMethod().invoke(bean, value);
				}
			}
			
		} catch (IntrospectionException e) {
			// TODO Auto-generated catch block
			LOGGER.error(e);
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			LOGGER.error(e);
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			LOGGER.error(e);
		} catch (InvocationTargetException e) {
			// TODO Auto-generated catch block
			LOGGER.error(e);
		}
		return bean;
	}
	/**
	 * 把map中key对象value转换成bean中的值
	 * @param bean
	 * @param map
	 * @return
	 */
	public static Object populate(Object bean,Map<String,String[]> map){
		try {	
			//获取类的信息
			BeanInfo bi = Introspector.getBeanInfo(bean.getClass(), Object.class);
			PropertyDescriptor[] pds = bi.getPropertyDescriptors();
			String[] values;
			Object value;
			Class clazz;
			for(PropertyDescriptor pd : pds){
				String name = pd.getName();
				values = map.get(name);
				if(values!=null&&values[0]!=null&&pd.getWriteMethod()!=null){
					
					clazz = pd.getPropertyType();
					if(java.util.Date.class.equals(clazz)){
						value = DateTool.getGridDate(values[0]);
					}else if(BigDecimal.class.equals(clazz)){
						value = new BigDecimal(values[0]);
					}else if(Double.class.equals(clazz)){
						value = new Double(values[0]);
					}else if(Integer.class.equals(clazz)){
						value = new Integer(values[0]);
					}else{
						value = values[0];
					}
					pd.getWriteMethod().invoke(bean, value);
				}
			}
			
		} catch (IntrospectionException e) {
			// TODO Auto-generated catch block
			LOGGER.error(e);
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			LOGGER.error(e);
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			LOGGER.error(e);
		} catch (InvocationTargetException e) {
			// TODO Auto-generated catch block
			LOGGER.error(e);
		}
		return bean;
	}
}